package com.spring.theory.boot.event;

import javax.annotation.Resource;

import lombok.extern.slf4j.Slf4j;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.event.EventListener;
import org.springframework.context.event.SimpleApplicationEventMulticaster;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Component;

/**
 * TestEvent1
 * 事件监听器第二种实现
 *
 * @author H
 * @version 1.0
 * @date 2024-02-01 17:25
 */
@Slf4j
@Configuration
public class TestEvent2 {

    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(TestEvent2.class);
        context.getBean(MyService.class).doBusiness();
        context.close();
    }

    static class MyEvent extends ApplicationEvent {
        public MyEvent(Object source) {
            super(source);
        }
    }

    @Component
    static class MyService {
        @Resource
        private ApplicationEventPublisher eventPublisher;

        public void doBusiness() {
            log.info("doBusiness 主线");
            eventPublisher.publishEvent(new MyEvent("发送事件"));
        }
    }

    @Component
    static class SmsService {
        @EventListener
        public void onApplicationEvent(MyEvent event) {
            log.info("SmsService 发送短信");
        }
    }

    @Component
    static class EmailService {
        @EventListener
        public void onApplicationEvent(MyEvent event) {
            log.info("EmailService 发送邮件");
        }
    }

    /**
     * 事件多线程执行
     * 事件发布底部可以设置使用线程池
     *
     * @param executor
     * @return
     */
    @Bean
    public SimpleApplicationEventMulticaster applicationEventMulticaster(ThreadPoolTaskExecutor executor) {
        SimpleApplicationEventMulticaster multicaster = new SimpleApplicationEventMulticaster();
        multicaster.setTaskExecutor(executor);
        return multicaster;
    }

    @Bean
    public ThreadPoolTaskExecutor executor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(3);
        executor.setMaxPoolSize(10);
        executor.setQueueCapacity(100);
        return executor;
    }

}
